#pragma once

namespace UI
{

// Forward declarations.
class Menu;

// Widget base class. Pure virtual since it is not meant to be instantiated.
class Widget
{
public:
	// Note: The position of the widget is in normalized screen coordinates. This means that the coordinates range from 0 to 1, where 1 represents the size of the screen.
	Widget( CIwFVec2 a_Position );
	~Widget();

	virtual void Update( float a_DT ) = 0;
	virtual void Render() = 0;
	virtual void Delete() = 0;

	UI::Menu* GetParentMenu();

	void SetOnDownMethod( void (*a_Method)( Widget* ) );
	void SetOnUpMethod( void (*a_Method)( Widget* ) );

	friend void UI::Page::AddWidget( UI::Widget* a_Widget );
	friend void UI::Page::SetParentMenu( UI::Menu* a_Menu );
protected:
	Widget() {}		// Private default c-tor.

	void SetParentMenu( UI::Menu* a_Menu );

	CIwFVec2 m_Position;			// The widget's position in normalized screen coordinates (0..1). This is useful if the app is deployed on systems with different screen resolutions.
	CIwSVec2 m_AbsolutePosition;	// The widget's absolute position (calculated from the normalized position and the screen resolution).

	UI::Menu* m_ParentMenu;

	bool m_Pressed;

	// Functors.
	void (*m_OnDownMethod)( Widget* );
	void (*m_OnUpMethod)( Widget* );
};

class Button
	: public UI::Widget
{
public:
	// Note: The position and size of the button are in normalized screen coordinates. This means that the coordinates range from 0 to 1, where 1 represents the size of the screen.
	Button( CIwFVec2 a_Position, CIwFVec2 a_Size, const char* a_ImageNormal, const char* a_ImageDown, void (*a_OnDownMethod)( Widget* ) = NULL, void (*a_OnUpMethod)( Widget* ) = NULL );
	~Button();

	void Update( float a_DT );
	void Render();
	void Delete();
private:

	CIwFVec2 m_Size;			// The button's size in normalized screen coordinates (0..1).
	CIwSVec2 m_AbsoluteSize;	// The button's absolute size.
	CIw2DImage* m_ImageNormal;
	CIw2DImage* m_ImageDown;
};

class Slider
	: public UI::Widget
{
public:
	// Note: The position and size of the button are in normalized screen coordinates. This means that the coordinates range from 0 to 1, where 1 represents the size of the screen.
	Slider( CIwFVec2 a_Position, CIwFVec2 a_Size, const char* a_ImageBase, float& a_Variable, float a_MinVal, float a_MaxVal, bool a_Reversed = false, void (*a_OnDownMethod)( Widget* ) = NULL, void (*a_OnUpMethod)( Widget* ) = NULL );
	~Slider();

	void Update( float a_DT );
	void Render();
	void Delete();

	const float& GetVariableRef();
private:

	CIwFVec2 m_Size;			// The size in normalized screen coordinates (0..1).
	CIwSVec2 m_AbsoluteSize;	// The absolute size.
	
	float m_SideSize, m_CenterSize;
	float& m_Variable;
	const float m_MinVal, m_MaxVal;

	bool m_Reversed;

	CIwSVec2 m_SliderSize;

	CIw2DImage* m_ImageLeft;
	CIw2DImage* m_ImageRight;
	CIw2DImage* m_ImageCenter;
	CIw2DImage* m_ImageSliderDown;
	CIw2DImage* m_ImageSliderUp;
};

class Image
	: public Widget
{
public:
	// Note: The position and size of the button are in normalized screen coordinates. This means that the coordinates range from 0 to 1, where 1 represents the size of the screen.
	Image( CIwFVec2 a_Position, CIwFVec2 a_Size, const char* a_Image );
	~Image();

	void Update( float a_DT );
	void Render();
	void Delete();
private:

	CIwFVec2 m_Size;			// The size in normalized screen coordinates (0..1).
	CIwSVec2 m_AbsoluteSize;	// The absolute size.

	CIw2DImage* m_Image;
};

}